/*
 * EventuallyStatementAst.cpp
 *
 *  Created on: 19 Nov 2010
 *      Author: kn308
 */

#include <MAlice/Parser/location.hh>
#include <MAlice/Ast/EventuallyStatementAst.h>
#include <MAlice/Ast/CastBooleanAst.h>
#include <MAlice/Codegen.h>

namespace MAlice
{

EventuallyStatementAst::EventuallyStatementAst(location loc, ExpressionAst* expr, StatementAst * body)
: mCond(expr), mBody(body), StatementAst(loc)
{
	MALICE_TRACE;

}

EventuallyStatementAst::~EventuallyStatementAst()
{
	MALICE_TRACE;
}

llvm::Value* EventuallyStatementAst::generate()
{
	MALICE_TRACE;
	Codegen* g = Codegen::get();
	Builder* builder = g->getBuilder();

	BasicBlock* currentBB = builder->GetInsertBlock();
	Function* F           = currentBB->getParent();
	BasicBlock* checkBB   = BasicBlock::Create(g->getContext(), "eventually.check", F);
	BasicBlock* trueBB    = BasicBlock::Create(g->getContext(), "eventually.true" , F);
	BasicBlock* mergeBB   = BasicBlock::Create(g->getContext(), "eventually.merge", F);

	// create jump from current basic block to start of eventually
	builder->CreateBr(checkBB);
	builder->SetInsertPoint(checkBB);

	Value* results;
	g->pushScope();
	{
		builder->CreateCondBr(mCond->generate(), trueBB, mergeBB);

		builder->SetInsertPoint(trueBB);
		results = mBody->generate();
		builder->CreateBr(checkBB);

	}
	g->popScope();

	F->getBasicBlockList().push_back(checkBB);
	F->getBasicBlockList().push_back(trueBB);
	F->getBasicBlockList().push_back(mergeBB);

	builder->SetInsertPoint(mergeBB);

	return results;
}

}
